package com.trinity.uniquefees.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.trinity.common.exception.ServiceException;
import com.trinity.common.utils.DateUtils;
import com.trinity.common.utils.StringUtils;
import com.trinity.common.utils.bean.BeanUtils;
import com.trinity.common.utils.bean.BeanValidators;
import com.trinity.uniquefees.domain.bo.UfCourseBook;
import com.trinity.uniquefees.domain.vo.UfCourseBookVo;
import com.trinity.uniquefees.mapper.UfCourseBookMapper;
import com.trinity.uniquefees.service.IUfCourseBookService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.List;

/**
 * 教材信息Service业务层处理
 *
 * @author 董诗攀
 * @date 2023-12-11
 */
@Service
public class UfCourseBookServiceImpl implements IUfCourseBookService {

    private static final Logger log = LoggerFactory.getLogger(UfCourseBookServiceImpl.class);
    @Resource
    private UfCourseBookMapper ufCourseBookMapper;

    @Resource
    protected Validator validator;

    /**
     * 查询教材信息
     *
     * @param courseId 教材信息主键
     * @return 教材信息
     */
    @Override
    public UfCourseBook selectUfCourseBookByCourseId(Long courseId) {
        return ufCourseBookMapper.selectUfCourseBookByCourseId(courseId);
    }

    @Override
    public List<UfCourseBook> selectUfCourseBookByListId(String lisId) {
        UfCourseBook queryDto = new UfCourseBook();
        queryDto.setScheduleId(lisId);
        return ufCourseBookMapper.selectUfCourseBookList(queryDto);
    }

    /**
     * 查询教材信息列表
     *
     * @param ufCourseBook 教材信息
     * @return 教材信息
     */
    @Override
    public List<UfCourseBook> selectUfCourseBookList(UfCourseBook ufCourseBook) {
        return ufCourseBookMapper.selectUfCourseBookList(ufCourseBook);
    }

    /**
     * 新增教材信息
     *
     * @param ufCourseBook 教材信息
     * @return 结果
     */
    @Override
    public int insertUfCourseBook(UfCourseBook ufCourseBook) {
        ufCourseBook.setCreateTime(DateUtils.getNowDate());
        return ufCourseBookMapper.insertUfCourseBook(ufCourseBook);
    }

    /**
     * 修改教材信息
     *
     * @param ufCourseBook 教材信息
     * @return 结果
     */
    @Override
    public int updateUfCourseBook(UfCourseBook ufCourseBook) {
        ufCourseBook.setUpdateTime(DateUtils.getNowDate());
        return ufCourseBookMapper.updateUfCourseBook(ufCourseBook);
    }

    /**
     * 批量删除教材信息
     *
     * @param courseIds 需要删除的教材信息主键
     * @return 结果
     */
    @Override
    public int deleteUfCourseBookByCourseIds(Long[] courseIds) {
        return ufCourseBookMapper.deleteUfCourseBookByCourseIds(courseIds);
    }

    /**
     * 删除教材信息信息
     *
     * @param courseId 教材信息主键
     * @return 结果
     */
    @Override
    public int deleteUfCourseBookByCourseId(Long courseId) {
        return ufCourseBookMapper.deleteUfCourseBookByCourseId(courseId);
    }

    /**
     * 删除教材信息信息
     *
     * @param listId 缴费项目
     * @return 结果
     */
    public int deleteUfCourseBookByListId(String listId) {
        LambdaQueryWrapper<UfCourseBook> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UfCourseBook::getScheduleId, listId); // 根据缴费项目进行删除
        return ufCourseBookMapper.delete(queryWrapper);
    }

    @Override
    public String importPaymentItem(List<UfCourseBookVo> list, String listId, String operName) {
        if (list == null || list.isEmpty()) {
            throw new ServiceException("导入教材数据不能为空！");
        }
        //填充空白值
        preprocessList(list);
        final String IMPORT_SUCCESS = " 导入成功";
        final String IMPORT_FAILURE = " 导入失败：";
        final String PRICE_EMPTY_MSG = "不导入：价格为空！";
        final String COURSE_NAME_EMPTY_MSG = "导入失败：课程名称为空！";
        final String COURSE_BOOK_EMPTY_MSG = "导入失败：教材名称为空！";
        //成功数据
        int successNum = 0;
        //失败数据
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        // 先删除原先的教材信息
        deleteUfCourseBookByListId(listId);
        //定义一个导入BO
        UfCourseBook ufCourseBook = new UfCourseBook();
        for (UfCourseBookVo course : list) {
            try {
                ufCourseBook.setScheduleId(listId);
                ufCourseBook.setCreateBy(operName);
                ufCourseBook.setCourseName(course.getCourseName());
                ufCourseBook.setCourseBook(course.getCourseBook());
                ufCourseBook.setPrice(convertPriceToCents(course.getPrice()));
                validateCourse(course);
                String msg = "<br/>" + (failureNum + 1) + "、 " + ufCourseBook.getCourseName() + ":" + ufCourseBook.getCourseBook();
                if (ufCourseBook.getCourseName() == null) {
                    failureNum++;
                    failureMsg.append(msg).append(COURSE_NAME_EMPTY_MSG);
                } else if (ufCourseBook.getCourseBook() == null) {
                    failureNum++;
                    failureMsg.append(msg).append(COURSE_BOOK_EMPTY_MSG);
                } else if (course.getPrice() == null) {
                    failureNum++;
                    failureMsg.append(msg).append(PRICE_EMPTY_MSG);
                } else if (ufCourseBook.getPrice() <= 0) {
                    failureNum++;
                    failureMsg.append(msg).append(PRICE_EMPTY_MSG);
                } else {
                    ufCourseBookMapper.insertUfCourseBook(ufCourseBook);
                    successNum++;
                    successMsg.append("<br/>")
                            .append(successNum)
                            .append("、").append(course.getCourseName())
                            .append(":")
                            .append(course.getCourseBook())
                            .append(IMPORT_SUCCESS);
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、 " + course.getCourseName() + ":" + course.getCourseBook() + IMPORT_FAILURE;
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg, e);
            }
        }
        return buildResultMessage(successNum, failureNum, successMsg, failureMsg);
    }

    /**
     * 填充空值 防止合并单元格情况出现
     * @param list
     */
    private void preprocessList(List<UfCourseBookVo> list) {
        String lastCourseName = null;
        String lastCourseBook = null;

        for (UfCourseBookVo course : list) {
            if (StringUtils.isEmpty(course.getCourseName())) {
                course.setCourseName(lastCourseName);
            } else {
                lastCourseName = course.getCourseName();
            }

            if (StringUtils.isEmpty(course.getCourseBook())) {
                course.setCourseBook(lastCourseBook);
            } else {
                lastCourseBook = course.getCourseBook();
            }
        }
    }
    /**
     * 价格转换
     *
     * @param price
     * @return
     */
    private long convertPriceToCents(String price) {
        if (price == null || price.isEmpty()) {
            return 0;
        }
        try {
            double priceDouble = Double.parseDouble(price);
            return (long) (priceDouble * 100);
        } catch (NumberFormatException e) {
            throw new ServiceException("价格格式不正确：" + price);
        }
    }

    private void validateCourse(UfCourseBookVo course) {
        BeanValidators.validateWithException(validator, course);
    }

    /**
     * 返回值
     *
     * @param successNum
     * @param failureNum
     * @param successMsg
     * @param failureMsg
     * @return
     */
    private String buildResultMessage(int successNum, int failureNum, StringBuilder successMsg, StringBuilder failureMsg) {

        if (failureNum > 0) {
            successMsg.insert(0, "导入成功数据，共 " + successNum + " 条，数据如下：");
            failureMsg.insert(0, "导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(successMsg.append("<br/><br/>").append(failureMsg).toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
